package com.liu.lab06.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.function.Function;


// 这是一个工具类 封装了SqlSessionFactory的静态方法
//用户可以更加方便的使用
// 使用方法： 导包
//import com.liu.lab06.utils.MybatsUtils;
// 直接使用 ： MybatsUtils.方法

public class MybatsUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            // 加载MyBatis配置文件
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("初始化MyBatis失败", e);
        }
    }

    /**
     * 获取SqlSession
     */
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }

    /**
     * 执行查询操作并返回单个结果
     * @param statement 映射语句的完全限定名 (namespace + id)
     * @param parameter 参数对象
     * @return 查询结果
     */
    public static <T> T selectOne(String statement, Object parameter) {
        try (SqlSession sqlSession = getSqlSession()) {
            return sqlSession.selectOne(statement, parameter);
        }
    }

    /**
     * 执行查询操作并返回结果列表
     * @param statement 映射语句的完全限定名 (namespace + id)
     * @return 结果列表
     */
    public static <T> List<T> selectList(String statement) {
        try (SqlSession sqlSession = getSqlSession()) {
            return sqlSession.selectList(statement);
        }
    }

    /**
     * 执行查询操作并返回结果列表
     * @param statement 映射语句的完全限定名 (namespace + id)
     * @param parameter 参数对象
     * @return 结果列表
     */
    public static <T> List<T> selectList(String statement, Object parameter) {
        try (SqlSession sqlSession = getSqlSession()) {
            return sqlSession.selectList(statement, parameter);
        }
    }

    /**
     * 执行插入操作
     * @param statement 映射语句的完全限定名 (namespace + id)
     * @param parameter 参数对象
     * @return 影响的行数
     */
    public static int insert(String statement, Object parameter) {
        try (SqlSession sqlSession = getSqlSession()) {
            int result = sqlSession.insert(statement, parameter);
            sqlSession.commit();//提交事务
            return result;
        }
    }

    /**
     * 执行更新操作
     * @param statement 映射语句的完全限定名 (namespace + id)
     * @param parameter 参数对象
     * @return 影响的行数
     */
    public static int update(String statement, Object parameter) {
        try (SqlSession sqlSession = getSqlSession()) {
            int result = sqlSession.update(statement, parameter);
            sqlSession.commit();
            return result;
        }
    }

    /**
     * 执行删除操作
     * @param statement 映射语句的完全限定名 (namespace + id)
     * @param parameter 参数对象
     * @return 影响的行数
     */
    public static int delete(String statement, Object parameter) {
        try (SqlSession sqlSession = getSqlSession()) {
            int result = sqlSession.delete(statement, parameter);
            sqlSession.commit();
            return result;
        }
    }

    /**
     * 执行数据库操作(事务管理)
     * @param function 数据库操作函数
     * @return 操作结果
     */
    public static <T> T execute(Function<SqlSession, T> function) {
        try (SqlSession sqlSession = getSqlSession()) {
            T result = function.apply(sqlSession);
            sqlSession.commit();
            return result;
        }
    }
}